#include "Object.h"
#include <iostream>
#include "Global.h"
#include <unistd.h>
#include <iomanip> // For setw and setfill
#include "Shop.h"
#include "LoginSignUp.h"

using namespace std;

/* ======================玩家类====================== */
Player::Player(int x, int y,const std::string& Name,const std::string& Symbol, int HP, int Attack, int Defends,int Exp,int Money)
    :VirtualObject(x, y, Name,Symbol, HP, Attack, Defends, Exp, Money)
    {
        Level =  0;
        b = new Bag;
    }

Player::~Player()
{
    delete b;
}

Bag* Player::GetBag()
{
    if(!b)
    {
        cout << "背包不存在" << endl;
    }
    return b;
}

void Player::OpenBag()
{
/* 背包操作接口 */
    if((GetBag()->GetProps()).empty())
    {
        cout << "背包为空！\n";
        sleep(2);
        return;
    }
    while(1)
    {
    std::cout << "请输入操作: (o 取出;p 卖出;q 退出;)"<<std::endl;
    char c = 0;
    std::cin>>c;
    
        switch (c)
        {
            case 'o':       //装备商品
            {
                const auto& props = b->GetProps();
                std::cout<<"请输入你选择的商品序号：\n";
                int index;
                std::cin >> index;
                PropPtr selectedProp = props[index - 1];
                if(selectedProp)
                {
                    if (index >= 1 && index <= props.size())
                    {
                        if (auto weapon = std::dynamic_pointer_cast<Weapon>(selectedProp))
                        {
                            SetAttack(GetAttack() + weapon->GetAttack());
                            std::cout<<weapon->GetGoodsName()<< "已装备。\n";
                                               
                        }
                        else if (auto defend = std::dynamic_pointer_cast<Defend>(selectedProp))
                        {
                            SetAttack(GetDefends() + defend->GetDefends());
                            std::cout<<defend->GetGoodsName()<< "已装备。\n";
                        }
                        else if (auto HP = std::dynamic_pointer_cast<Medicine>(selectedProp))
                        {
                            SetAttack(GetHP() + HP->GetHP());
                            std::cout<<HP->GetGoodsName()<< "已装备。\n";
                        }
                        b->Discard(index);
                        show();
                        b->show();
                    }
                    else
                    {
                        std::cout<<"按键输入错误, 请重新输入!\n";
                        sleep(2);
                    }
                    break;
                }
            }
            case 'p':
            {
                std::cout<<"请输入你要卖出的商品序号：\n";
                int index;
                std::cin >> index;
                SetMoney(GetMoney() + b->Sale(index));
                std::cout<<"您已成功卖出商品！\n";
                show();
                b->show();
                break;
            }
            case 'q':return;
        }
    }
}   

void Player::Move(Scene & s)
{
    cout << "||  请输入移动方向:(w 向上;s 向下;a 向左;d 向右;)   ||\n";
    cout << "||  其 他 选 择:(1 打开商店;2 打开背包;)            ||\n";
    cout << "||  账 号 管 理:(3 修改密码;4 删除账号;5 暂停游戏;) ||\n";
    cout << "======================================================\n";

    char c = 0;         //输入的是字符
    cin>>c;
    switch (c)
    {
        case 'w': SetY(GetY() - 1); break;      //上下移动
        case 's': SetY(GetY() + 1); break;
        case 'a': SetX(GetX() - 1); break;      //左右移动
        case 'd': SetX(GetX() + 1); break;
        case '1':
        {
            Shop shop(*this);
            shop.show();
            break;
        } 
        case '2':
        {
            GetBag()->show();
            OpenBag();
            break;
        }
        case '3':
        {
            string Passwd;
            Login login;
            cout << "请输入新的密码：\n";
            cin >> Passwd;
            login.ChangPasswd(p.GetName(),Passwd);

            break;
        }
        case '4':
        {
            string UserName;
            Login login;
            cout << "请输入要删除的账号名称：\n";
            cin >> UserName;
            login.RemoveUser(UserName);
            break;
        }
        case '5':
        {
            system("clear");
            cout << endl;
            cout << endl;
            cout << "======================暂 停 页 面========================\n";
            cout << "||                                                     ||\n";
            cout << "||   1、保存；2、继续游戏；3、退出登录；4、退出游戏；  ||\n";
            cout << "||                                                     ||\n";
            cout << "========================================================\n";

            char c;
            cin >> c;
            if(c == '1')
            {
                s.SaveGame();
                sleep(1);
                break;
            }
            else if(c == '2')
            {
                break;
            }
            else if(c == '3')
            {
                Screen::getInstance().show();   // 返回主页面
                break;
            }
            else if(c == '4')
            {
                cout << "感谢游玩魔塔世界，再见！" << endl;
                sleep(1);
                exit(-1);
            }
            else
            {
                cout << " 无效操作，请重新输入：" << endl;
            }
            sleep(1);
        }
        default:
            break;
    }
    //越界则在（0，0）位置
    if(GetX() < 0)SetX(0);
    if(GetY() < 0)SetY(0);
    //越最大界则放置于边界
    if(GetX() >= MapSize) SetX(MapSize - 1);
    if(GetY() >= MapSize) SetY(MapSize - 1);
}

/* 打印玩家信息 */
void Player::show()
{
    std::cout<<"=======================玩  家👑=======================\n";
    std::cout<<"||                  "<<GetSymbol()<<"  "<<setw(6)<<left<<GetName()<<""<<"                      ||"<<std::endl;
    std::cout<<"||   "<<"血    量🩸 |"<<setw(5)<<left<<GetHP()<<"|       "<<"金    钱💰 |"<<setw(5)<<left<<GetMoney()<<"|"<<"    ||"<<std::endl;
    std::cout<<"||   "<<"攻 击 力💣 |"<<setw(5)<<left<<GetAttack()<<"|      "<<" 防 御 力🧥 |"<<setw(5)<<left<<GetDefends()<<"|"<<"    ||"<<std::endl;
    std::cout<<"||   "<<"等    级📚 |"<<setw(5)<<left<<GetLevel()<<"|      "<<" 经 验 值📃 |"<<setw(5)<<left<<GetExp()<<"|"<<"    ||"<<std::endl;
    std::cout<<"======================================================\n";

}
/* 等级提升规则：经验值满一百则加一等级，升一等级则血条加30，攻击力加一，防御力加一 */
void Player::LevelUp()
{
    while(GetExp() >= 100)
    {
        Level++;
        SetExp(GetExp() - 100);
        printf("恭喜升级！\n");

        SetHP(GetHP() + 30);
        SetAttack(GetAttack() + 1);
        SetDefends(GetDefends() + 1);
    }
}



/* ======================怪兽类====================== */
Monster::Monster(int x, int y, const std::string &Name, const std::string &Symbol, int HP, int Attack, int Defends, int Exp,int Money)
    :VirtualObject(x, y, Name,Symbol, HP, Attack, Defends,Exp,Money)
{
    MaxHP = HP;
}

void Monster::show()
{
    std::cout<<"=======================怪  兽👿=======================\n";
    std::cout<<"||                  "<<GetSymbol()<<"  "<<setw(6)<<left<<GetName()<<""<<"                      ||"<<std::endl;
    std::cout<<"||   "<<"血    量🩸 |"<<setw(5)<<left<<GetHP()<<"|       "<<"金    钱💰 |"<<setw(5)<<left<<GetMoney()<<"|"<<"    ||"<<std::endl;
    std::cout<<"||   "<<"攻 击 力💣 |"<<setw(5)<<left<<GetAttack()<<"|      "<<" 防 御 力💊 |"<<setw(5)<<left<<GetDefends()<<"|"<<"    ||"<<std::endl;
    std::cout<<"======================================================\n";
}

/* ======================背包类====================== */
void Bag::Insert(const PropPtr &p)
{
    if(p)
    {
        props.push_back(p);
    }
    else
    {
        cout << "没能插入数组" << endl;
    }
    
}

void Bag::show()
{
    std::cout<<"=======================背  包🎒=======================\n";
    int count = 1;
    for (const auto& prop : props) 
    {
        std::cout << "  " << count++ << ". 名  称🔖: " << prop->GetGoodsName() << "     金  额💸: " << prop->GetGoodsMoney() << std::endl;
        if (auto weapon = std::dynamic_pointer_cast<Weapon>(prop)) 
        {
            std::cout << "  " << "   武 器->增加攻击力💣: " << weapon->GetAttack() << std::endl;
        }
        else if (auto defend = std::dynamic_pointer_cast<Defend>(prop)) 
        {
            std::cout << "  " << "  盾牌->增加防御力🧥: " << defend->GetDefends() << std::endl;
        } 
        else if (auto HP = std::dynamic_pointer_cast<Medicine>(prop)) 
        {
            std::cout << "  " << "  药品->恢复生命值💊: " << HP->GetHP() << std::endl;
        }
    }
    std::cout<<"======================================================\n";
}

/* 卖出 */
int Bag::Sale(int index)
{
    if (index >= 1 && index <= props.size())
    {
        //找到要删除的位置
        auto selectedProp = props[index - 1]; // Adjust index for zero-based array
        //知道商品价格
        int money = selectedProp->GetGoodsMoney() / 2;
        //将该商品删除
        props.erase(props.begin()+(index - 1));
        //返回该商品价格以备后续返回到用户手里
        return money;
        show();
    }
    else
    {
        std::cout<<"  按键输入错误, 请重新输入!\n";
        return 0;
    }
    return 0;
}
    

